home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
FPTOSTR_
/
GVWUTILS.C1
< prev
next >
Wrap
Text File
|
1989-05-22
|
8KB
|
289 lines
/************************************************************************
GVWUtils881.c
====== USE THIS SOURCE ONLY IF THE MC68881/2 MATH ====
====== CO-Processor IS BEING USED! ====
This is a collection of utility routines, some gleaned from
Compuserve, and others from various other sources.
Copyright ⌐ 1988,1989 George V. Woodrow III. All Rights Reserved
Author: George V. Woodrow III
Created: September 12, 1988
Last Revision: 8:52:21 PM 5/22/89
Revision History:
9:22:12 AM 5/22/89 Added code to allow correct operation with
FPU.
8:52:21 PM 5/22/89 removed non-standard #defines
***********************************************************************/
#include "MacTypes.h"
#include <math.h> /* has the typedef for Extended80. etc */
/***********************************************************************
CONTENTS:
1. Boolean str2fp(buf,x) converts string to float
2. StringPtr fp2str(x,buf,fmt,ndec) converts fp to string
************************************************************************/
/**********************************************************************
* Code from LSC MathHybrid to handle conversion from the SANE double
* (80 bits) to the 881 double (96 bits), and back. This is necessary
* because the Dec2Str() routine expects a SANE double.
***********************************************************************/
/* the 80-bit extended "_x80" is used as the destination to convert the
arguments to SANE doubles. */
static Extended80 _x80;
/* routines for conversion between 80- and 96-bit formats */
void x80tox96(x80, x96)
register Extended80 *x80;
register Extended96 *x96;
{
(*x96).exponent = (*x80).exponent;
(*x96).reserved = 0;
(*x96).mantissa = (*x80).mantissa;
}
void x96tox80(x96, x80)
register Extended96 *x96;
register Extended80 *x80;
{
(*x80).exponent = (*x96).exponent;
(*x80).mantissa = (*x96).mantissa;
}
#define _x80tox96(x80, x96) x80tox96(&x80, &x96)
#define _x96tox80(x96, x80) x96tox80(&x96, &x80)
#define _to80(x) _x96tox80(x, _x80);
#define _to96(x) _x80tox96(_x80, x);
/***********************************************************************
str2fp(buf,x)
converts string in buf to double, x
Uses SANE, but does not need sane.h, the structures required are defined
fp2str(x,buf,fmt,ndec)
converts double x into string put in buf
fmt = 0 floating point style x.xx e yy
= 1 fixed point xxx.xx
ndec float: number of significant digits
fixed: number of digits to right of decimal
Unknown download from Compuserve. [75236,3146]
Some corrections and clarifications made.
12/6/88 fp2str modified to allow extra arguments
************************************************************************/
/*
* The first structure represents formatting information.
* Apple Numerics Manual,2nd edition, p 26. q.v. for more info.
*
* The next structure represents floats: the value v is
*
* v = (-1) ^sgn * sig * 10 ^ exp
*
* Apple Numerics Manual 2nd edition, p 27 q.v. for more info
*/
struct decform {
char style; /* 0 = floating point style x.xx e ▒yy
1 = fixed style xx.xxx */
short digits; /* float: # of sig digits
fixed: # of digits to right of decimal */
};
struct decimal {
char sgn; /* sign 0 = pos, 1 = neg */
short exp; /* exponent 16 bit integer */
unsigned char sig[21]; /* significand as decimal integer */
};
pascal void Dec2Str(), Str2Dec(); /* SANE procedures */
/** PROCEDURE Dec2Str(f: DecForm; d: Decimal; var s: DecStr);
is described on p 31 of the Apple Numerics Manual. You set up the
DecForm f and stuff the number into Decimal d, and the function will
stick the string into the string s. You pass its address.
PROCEDURE Str2Dec(s: DecStr; var Index: integer; var d: Decimal;
var ValidPrefix: Boolean );
is described on p 30 of the Apple Numerics Manual. Index should
point to thestarting position in the string; on output, it is one
greater than the position of the last character in the numeric
substring just parsed. If no numeric substring is recognized, it
retains the same value. Boolean is true if all went well. **/
/**************************************************
fp2str(x, buf,fmt,ndec)
send it x, a floating point number, fmt, the type of represenatation,
ndec, the number of digits, and buf, a string pointer.
the function returns a pointer to the converted string
which may be buf, or buf[1]
Sample use:
double x;
Str255 buf1;
StringPtr buf2;
StringPtr fp2str();
TextFont(4);
x = 125823.452258985412026;
MoveTo( 10,20);
DrawString(fp2str(x, buf1,0,5));
The following is an example of how to right justify a number.
In practice, the field width would be a variable, and you would
need to check to make sure that buf[0] is <= the field width.
Note that this procedure requires monospaced fonts.
x = 78.357*9;
MoveTo( 150,20);
DrawString(fp2str(x,buf1,0,5));
for (i = 0 ;i < 15 ; i++)
{
buf2 = fp2str(x,buf1,1,3);
MoveTo( 150,12*(i+6));
for (j = 1 ; j < 10 - buf2[0] ; DrawChar(32) , j++ )
;
DrawString(buf2);
x -= 78.357;
};
end of formatting demo
**********************************************************************/
StringPtr fp2str(x, buf, fmt, ndec)
double x; /* actually an Extended96 */
StringPtr buf;
char fmt;
short ndec;
{
struct decform f;
struct decimal d;
int i;
/* convert float --> decimal record */
/* convert to sane double */
_to80(x); /* _x80 has result */
f.style = fmt;
f.digits = ndec;
asm {
pea f
pea _x80
pea d
move.w #0x000B,-(sp)
_FP68K
} /* end of asm */
/* convert decimal record --> string */
if (d.sig[1] == '0') /* is number 0 ? */
{
f.style = 1; /* fixed style */
}
else /* number is not 0 */
{
for (i = d.sig[0]; i > 1 && d.sig[i] == '0'; --i, ++d.exp)
;
d.sig[0] = i;
i = -d.exp;
if (i> ndec)
{
f.digits = i;
}
} /* end of if--else */
Dec2Str(f, &d, buf);
/* put a leading space in front of positive numbers in fixed format */
if (x > 0 && fmt == 1)
{
for (i = buf[0] +1 ; i > 1 ; i--)
{
buf[i] = buf[i-1];
}
buf[0]++;
buf[1] = ' ';
}
return(&buf[0]);
} /* end of fp2str() */
/************************************************************************
str2fp() - convert string to float
returns TRUE if conversion was ok
Sample use:
x = 123.45686;
buf2 = fp2str(x,buf1,1,6);
MoveTo( 20,270);
DrawString(buf2); show whole number
buf2 = fp2str(x,buf1,1,3);
MoveTo( 120,270);
DrawString(buf2); show truncated number
i = str2fp(buf2,&x); turn string into number
buf2 = fp2str(x,buf1,1,6);
MoveTo( 320,270);
DrawString(buf2); show whole number
the output is 123.456860 123.457 123.457000
********************************************************************/
Boolean str2fp(buf, x)
StringPtr buf;
double *x;
{
short i, n, valid;
struct decimal d;
/* trim trailing blanks */
for (n = buf[0]; buf[n] == ' '; --n)
;
buf[0] = n;
/* convert string --> decimal record */
i = 1;
Str2Dec(buf, &i, &d, &valid);
if (i <= n)
return(false);
/* convert decimal record --> float */
asm {
pea d
move.l _x80,-(sp)
move.w #0x0009,-(sp)
_FP68K
}
_to96(*x);
return(true);
}